﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Web.Mvc;
using MvcContrib.Filters;
using Peak.Web.Controllers.ErrorHandlers;
using Peak.Web.Controllers.Models;
using Peak.Web.Controllers.Services;
using Peak.Core;
using Peak.Resources;
using System.Security;

namespace Peak.Web.Controllers
{  
  [ProjectNotSelectedHandler]
  [EntityNotFoundHandler]
  [SecurityExceptionHandler]
  [HandleError(Order = 4)]
  [Authorize]  
  public class BaseController : Controller
  {
    protected readonly ISessionService _sessionService;

    public BaseController(ISessionService sessionService)
    {
      _sessionService = sessionService;
    }

    public new ActionResult View()
    {
      _sessionService.BackLink.Push(Request.Url);
      return base.View();
    }

    public new ActionResult View(string viewName)
    {
      _sessionService.BackLink.Push(Request.Url);
      return base.View(viewName);
    }

    public new ActionResult View(string viewName,object model)
    {
      _sessionService.BackLink.Push(Request.Url);
      return base.View(viewName,model);
    }

    public new ActionResult View(IView view)
    {
      _sessionService.BackLink.Push(Request.Url);
      return base.View(view);
    }

    public new ActionResult View(IView view,object model)
    {
      _sessionService.BackLink.Push(Request.Url);
      return base.View(view,model);
    }
    
    public new ActionResult View(object model)
    {
      _sessionService.BackLink.Push(Request.Url);
      return base.View(model);
    }

    public ActionResult Back()
    {
      Uri url = _sessionService.BackLink.Pop();
      if(url == null)
      {
        return this.RedirectToAction<DashboardController>(f => f.Index(null));
      }
      return Redirect(url.PathAndQuery);
    }


    public ActionResult RedirectToThis()
    {
      return Redirect(_sessionService.BackLink.CurrentUrl.PathAndQuery);
    }

    public ActionResult MessageBox(string message)
    {
      return View("MessageBox", new MessageBoxModel() {Message = message});
    }

    public string BuildUrlFromExpression<T>(Expression<Action<T>> action) where T : Controller
    {
      MethodCallExpression body = action.Body as MethodCallExpression;
      if (body == null)
        throw new InvalidOperationException("Expression must be a method call.");

      if (body.Object != action.Parameters[0])
        throw new InvalidOperationException("Method call must target lambda argument.");

      string actionName = body.Method.Name;
      string controllerName = typeof(T).Name;

      if (controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
        controllerName = controllerName.Remove(controllerName.Length - 10, 10);

      RouteValueDictionary values = new RouteValueDictionary();
      values.Add("controller", controllerName);
      values.Add("action", actionName);
      VirtualPathData vpd = ControllerContext.RouteData.Route.GetVirtualPath(ControllerContext.RequestContext, values);
      return (vpd == null) ? null : "~/"+vpd.VirtualPath;
    }
  }
}
